from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import QMainWindow, QWidget
from view import Ui_MainWindow
from secondview import Ui_Form
from function import runEventSchedule, runKnapsack
import random as rd


class MyWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MyWindow, self).__init__()
        self.setupUi(self)
        self.setWindowTitle("活动安排问题")
        self.input_n.setPlaceholderText("请先输入一个正整数")
        self.input_s.setPlaceholderText("请输入一个以英文逗号隔开的实数数组，长度为输入的整数")
        self.input_f.setPlaceholderText("请输入一个每一位元素都要比上一个数组的对应数值大的等长数组")

        # 输入限制
        regx = QtCore.QRegExp("([0-9])*")
        intVal = QtGui.QRegExpValidator(self.input_n)
        intVal.setRegExp(regx)
        self.input_n.setValidator(intVal)

        regx1 = QtCore.QRegExp("(([0-9]+(\.[0-9]+)?)\,)*")
        validator1 = QtGui.QRegExpValidator(self.input_s)
        validator1.setRegExp(regx1)
        self.input_s.setValidator(validator1)
        validator1 = QtGui.QRegExpValidator(self.input_f)
        validator1.setRegExp(regx1)
        self.input_f.setValidator(validator1)


        self.run_Btn.clicked.connect(self.fun_run_Btn)
        self.test_Btn.clicked.connect(self.fun_test_Btn)
        self.show()

    def fun_run_Btn(self):
        print("run")
        self.output.clear()
        # check
        n = self.input_n.text()
        tmp_s = self.input_s.text()
        tmp_s = tmp_s.split(',')
        s = [float(x) for x in tmp_s if x is not '']
        tmp_f = self.input_f.text()
        tmp_f = tmp_f.split(',')
        f = [float(x) for x in tmp_f if x is not '']
        if n is '':
            self.output.setText("请先输入事件数目")
            return
        else:
            n = int(n)
        if s.__len__() != n or f.__len__() != n:
            self.output.clear()
            self.output.setText("请正确输入“每个事件的起止时间！”\n不要多输入或少输入")
            return
        else:
            for i in range(n):
                if s[i] >= f[i]:
                    self.output.setText("事件的起始时间必须小于结束时间！")
                    return
            ans = runEventSchedule(n, s, f)
            self.output.setText("排序后\n开始时间列表：" + str(s) + "\n结束时间列表：" + str(f) + "\n最多相容事件为事件：" + str(ans))


    def fun_test_Btn(self):
        ans = "测试数据："
        for _ in range(5):
            n = rd.randint(10, 99)
            s = [rd.randint(0, 999) for i in range(n)]
            f = [x + rd.randint(1, 999) for x in s]
            event = runEventSchedule(n, s, f)
            ans += "\n事件数目：" + str(n) + "\n开始时间列表：" + str(s) + "\n结束时间列表：" + str(f) + \
                   "\n输出结果：" + str(event)
        self.output.setText(ans)


class SecWindow(QWidget, Ui_Form):
    def __init__(self):
        super(SecWindow, self).__init__()
        self.setupUi(self)
        self.setWindowTitle("一般背包问题")
        self.input_n.setPlaceholderText("请输入一个正整数")
        self.input_c.setPlaceholderText("请输入一个实数")
        self.input_w.setPlaceholderText("请输入一个以英文逗号隔开的实数数组，长度为输入的正整数")
        self.input_v.setPlaceholderText("请输入一个以英文逗号隔开的实数数组，长度为输入的正整数")

        # 输入限制
        regx = QtCore.QRegExp("([0-9])*")
        intVal = QtGui.QRegExpValidator(self.input_n)
        intVal.setRegExp(regx)
        self.input_n.setValidator(intVal)
        regx2 = QtCore.QRegExp("([0-9])+(\.[0-9]+)?")
        floatVal = QtGui.QRegExpValidator(self.input_c)
        floatVal.setRegExp(regx2)
        self.input_c.setValidator(floatVal)

        regx1 = QtCore.QRegExp("(([0-9]+(\.[0-9]+)?)\,)*")
        validator1 = QtGui.QRegExpValidator(self.input_w)
        validator1.setRegExp(regx1)
        self.input_w.setValidator(validator1)
        validator1 = QtGui.QRegExpValidator(self.input_v)
        validator1.setRegExp(regx1)
        self.input_v.setValidator(validator1)

        self.run_Btn.clicked.connect(self.fun_run_Btn)
        self.test_Btn.clicked.connect(self.fun_test_Btn)

    def fun_run_Btn(self):
        # print("run")
        n = self.input_n.text()
        c = self.input_c.text()
        tmp_w = self.input_w.text()
        tmp_w = tmp_w.split(',')
        w = [float(x) for x in tmp_w if x is not '']
        tmp_v = self.input_v.text()
        tmp_v = tmp_v.split(',')
        v = [float(x) for x in tmp_v if x is not '']
        if '' in [n, c]:
            self.output.clear()
            self.output.setText("请先输入物品数目和背包承重")
            return
        else:
            n = int(n)
            c = int(c)
        if w.__len__() != n or v.__len__() != n:
            self.output.clear()
            self.output.setText("请正确输入“每样物品的重量和价值！”\n不要多输入或少输入")
            return
        else:
            maxvalue, x = runKnapsack(n, c, w, v)
            ans = "\n最大价值：" + str(maxvalue) + "\n背包中所选物品序号：" + ','.join([str(i) for i in range(len(x)) if x[i] != 0]) + \
                  "\n物品选择情况：" + str(x[1:])
            self.output.setText(ans)

    def fun_test_Btn(self):
        self.output.clear()
        self.input_n.clear()
        self.input_c.clear()
        self.input_w.clear()
        self.input_v.clear()
        ans = "测试数据:"
        for _ in range(5):
            n = rd.randint(4, 20)  # 随机一个物品个数
            c = rd.randint(10, 200)  # 随机一个背包容量
            w = [rd.randint(1, c) for i in range(n)]
            v = [rd.randint(1, 1000) for i in range(n)]
            ans += "\n物品个数：" + str(n) + "\n背包容量：" + str(c) + "\n相应重量：" + str(w) + "\n价值：" + str(v)
            maxvalue, x = runKnapsack(n, c, w, v)
            ans += "\n最大价值：" + str(maxvalue) + "\n背包中所选物品序号：" + ','.join([str(i) for i in range(len(x)) if x[i] != 0]) + \
                   "\n物品选择情况：" + str(x[1:])
        self.output.setText(ans)
